"use client";

import * as React from "react";
import { PaginationState, SortingState, ColumnFiltersState, GroupingState } from "@tanstack/react-table";
import { ClientVirtualTable } from "@/components/client-table-v2/client-virtual-table";
import { TestProduct } from "@/db/schema/test-table-v2";
import { productColumns, orderColumns } from "./columns";
import { OrderWithDetails } from "./column-defs";
import { 
  getAllProducts, 
  getProductTableData, 
  getOrderTableData,
  getProductTableDataWithGrouping,
  GroupInfo,
} from "./actions";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { ChevronDown, ChevronRight, Loader2 } from "lucide-react";
import { cn } from "@/lib/utils";

// ============================================================
// Reusable Loading Overlay Component
// ============================================================

function LoadingOverlay({ 
  isLoading, 
  children 
}: { 
  isLoading: boolean; 
  children: React.ReactNode 
}) {
  return (
    <div className="relative">
      {children}
      {isLoading && (
        <div className="absolute inset-0 z-50 flex items-center justify-center bg-background/60 backdrop-blur-[2px] transition-all duration-200">
          <div className="flex items-center gap-2 px-4 py-2 bg-background rounded-lg shadow-lg border">
            <Loader2 className="h-5 w-5 animate-spin text-primary" />
            <span className="text-sm text-muted-foreground">Loading...</span>
          </div>
        </div>
      )}
    </div>
  );
}

// ============================================================
// Pattern 1: Client-Side Table
// ============================================================

function ClientSideTable() {
  const [data, setData] = React.useState<TestProduct[]>([]);
  const [isLoading, setIsLoading] = React.useState(true);

  React.useEffect(() => {
    const fetchData = async () => {
      setIsLoading(true);
      try {
        const products = await getAllProducts();
        setData(products);
      } catch (error) {
        console.error("Failed to fetch products:", error);
      } finally {
        setIsLoading(false);
      }
    };

    fetchData();
  }, []);

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center gap-2">
          <CardTitle>Pattern 1: Client-Side</CardTitle>
          <Badge variant="outline">fetchMode=&quot;client&quot;</Badge>
        </div>
        <CardDescription>
          모든 데이터를 한 번에 받아와 클라이언트에서 필터링/정렬/페이지네이션/그룹핑 처리합니다.
          <br />
          <span className="text-muted-foreground">
            적합: 데이터 1000건 이하, 빠른 인터랙션 필요 시
          </span>
          <br />
          <span className="text-emerald-600 text-sm">
            ✅ 그룹핑: 헤더 우클릭 → Group by [Column]
          </span>
        </CardDescription>
      </CardHeader>
      <CardContent>
        <LoadingOverlay isLoading={isLoading}>
          <div className="h-[500px]">
            <ClientVirtualTable
              fetchMode="client"
              data={data}
              columns={productColumns}
              isLoading={false} // LoadingOverlay로 처리
              enablePagination
              enableGrouping
              height="100%"
              enableUserPreset={true}
              tableKey="test-table-v2-pattern1"
            />
          </div>
        </LoadingOverlay>
      </CardContent>
    </Card>
  );
}

// ============================================================
// Pattern 2: Factory Service (Server-Side)
// ============================================================

function FactoryServiceTable() {
  const [data, setData] = React.useState<TestProduct[]>([]);
  const [totalRows, setTotalRows] = React.useState(0);
  const [isLoading, setIsLoading] = React.useState(true);

  // Table state
  const [pagination, setPagination] = React.useState<PaginationState>({
    pageIndex: 0,
    pageSize: 10,
  });
  const [sorting, setSorting] = React.useState<SortingState>([]);
  const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([]);
  const [globalFilter, setGlobalFilter] = React.useState("");

  // Fetch data on state change
  React.useEffect(() => {
    const fetchData = async () => {
      setIsLoading(true);
      try {
        const result = await getProductTableData({
          pagination,
          sorting,
          columnFilters,
          globalFilter,
        });
        setData(result.data);
        setTotalRows(result.totalRows);
      } catch (error) {
        console.error("Failed to fetch products:", error);
      } finally {
        setIsLoading(false);
      }
    };

    fetchData();
  }, [pagination, sorting, columnFilters, globalFilter]);

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center gap-2">
          <CardTitle>Pattern 2: Factory Service</CardTitle>
          <Badge variant="outline">fetchMode=&quot;server&quot;</Badge>
          <Badge variant="secondary">createTableService</Badge>
        </div>
        <CardDescription>
          <code>createTableService</code>로 서버 액션을 자동 생성합니다.
          <br />
          <span className="text-muted-foreground">
            적합: 단순 CRUD, 마스터 테이블 조회
          </span>
          <br />
          <span className="text-amber-600 text-sm">
            ⚠️ 그룹핑: 서버 모드에서는 별도 구현 필요 (Pattern 2-B 참고)
          </span>
        </CardDescription>
      </CardHeader>
      <CardContent>
        <LoadingOverlay isLoading={isLoading}>
          <div className="h-[500px]">
            <ClientVirtualTable
              fetchMode="server"
              data={data}
              rowCount={totalRows}
              columns={productColumns}
              isLoading={false}
              enablePagination
              enableGrouping={false}
              height="100%"
              pagination={pagination}
              onPaginationChange={setPagination}
              sorting={sorting}
              onSortingChange={setSorting}
              columnFilters={columnFilters}
              onColumnFiltersChange={setColumnFilters}
              globalFilter={globalFilter}
              onGlobalFilterChange={setGlobalFilter}
              enableUserPreset={true}
              tableKey="test-table-v2-pattern-2-A"
            />
          </div>
        </LoadingOverlay>
      </CardContent>
    </Card>
  );
}

// ============================================================
// Pattern 2-B: Server-Side Grouping (Context Menu 방식)
// ============================================================

function ServerGroupingTable() {
  const [grouping, setGrouping] = React.useState<GroupingState>([]);
  const [expandedGroups, setExpandedGroups] = React.useState<string[]>([]);
  const [groups, setGroups] = React.useState<GroupInfo[]>([]);
  const [flatData, setFlatData] = React.useState<TestProduct[]>([]);
  const [isGrouped, setIsGrouped] = React.useState(false);
  const [isLoading, setIsLoading] = React.useState(true);
  const [totalRows, setTotalRows] = React.useState(0);
  const [sorting, setSorting] = React.useState<SortingState>([]);

  const [pagination, setPagination] = React.useState<PaginationState>({
    pageIndex: 0,
    pageSize: 10,
  });

  // 데이터 페칭
  React.useEffect(() => {
    const fetchData = async () => {
      setIsLoading(true);
      try {
        const result = await getProductTableDataWithGrouping(
          { pagination, grouping, sorting },
          expandedGroups
        );
        
        if ('groups' in result) {
          setGroups(result.groups);
          setIsGrouped(true);
          setFlatData([]);
        } else {
          setFlatData(result.data);
          setTotalRows(result.totalRows);
          setIsGrouped(false);
          setGroups([]);
        }
      } catch (error) {
        console.error("Failed to fetch:", error);
      } finally {
        setIsLoading(false);
      }
    };

    fetchData();
  }, [pagination, grouping, sorting, expandedGroups]);

  // 그룹 토글
  const toggleGroup = (groupKey: string) => {
    setExpandedGroups(prev => 
      prev.includes(groupKey) 
        ? prev.filter(k => k !== groupKey)
        : [...prev, groupKey]
    );
  };

  // 그룹핑 상태 변경 핸들러 (Context Menu에서 호출됨)
  const handleGroupingChange = React.useCallback((updater: GroupingState | ((old: GroupingState) => GroupingState)) => {
    const newGrouping = typeof updater === 'function' ? updater(grouping) : updater;
    setGrouping(newGrouping);
    setExpandedGroups([]); // 그룹핑 변경 시 확장 상태 초기화
  }, [grouping]);

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center gap-2">
          <CardTitle>Pattern 2-B: Server-Side Grouping</CardTitle>
          <Badge variant="outline">fetchMode=&quot;server&quot;</Badge>
          <Badge className="bg-emerald-500">GROUP BY</Badge>
        </div>
        <CardDescription>
          서버에서 GROUP BY + 집계 쿼리로 그룹 정보를 조회합니다.
          <br />
          <span className="text-emerald-600 text-sm">
            ✅ 그룹핑: 헤더 우클릭 → Group by [Column] (category, status, isNew만 지원)
          </span>
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-4">
        {/* 현재 그룹핑 상태 표시 */}
        {grouping.length > 0 && (
          <div className="flex items-center gap-2 text-sm">
            <span className="text-muted-foreground">Grouped by:</span>
            {grouping.map((col) => (
              <Badge key={col} variant="secondary">
                {col}
                <button
                  className="ml-1 hover:text-destructive"
                  onClick={() => setGrouping([])}
                >
                  ×
                </button>
              </Badge>
            ))}
          </div>
        )}

        {/* Content with Loading Overlay */}
        <LoadingOverlay isLoading={isLoading}>
          <div className="border rounded-md min-h-[400px] max-h-[500px] overflow-auto">
            {isGrouped ? (
              // Grouped View - Custom Rendering
              <div className="divide-y">
                {groups.length === 0 ? (
                  <div className="flex items-center justify-center h-[400px] text-muted-foreground">
                    No data
                  </div>
                ) : (
                  groups.map((group) => (
                    <div key={group.groupKey}>
                      {/* Group Header */}
                      <button
                        className="w-full px-4 py-3 flex items-center gap-3 hover:bg-muted/50 transition-colors text-left"
                        onClick={() => toggleGroup(group.groupKey)}
                      >
                        {expandedGroups.includes(group.groupKey) ? (
                          <ChevronDown className="w-4 h-4" />
                        ) : (
                          <ChevronRight className="w-4 h-4" />
                        )}
                        <span className="font-medium">
                          {grouping[0]}: <Badge variant="outline">{String(group.groupValue)}</Badge>
                        </span>
                        <span className="text-muted-foreground text-sm">
                          ({group.count} items)
                        </span>
                      </button>
                      
                      {/* Expanded Rows */}
                      {expandedGroups.includes(group.groupKey) && group.rows && (
                        <div className="bg-muted/20 border-t">
                          <table className="w-full text-sm">
                            <thead>
                              <tr className="border-b bg-muted/30">
                                <th className="px-4 py-2 text-left">ID</th>
                                <th className="px-4 py-2 text-left">SKU</th>
                                <th className="px-4 py-2 text-left">Name</th>
                                <th className="px-4 py-2 text-left">Price</th>
                                <th className="px-4 py-2 text-left">Stock</th>
                              </tr>
                            </thead>
                            <tbody>
                              {group.rows.map((row) => (
                                <tr key={row.id} className="border-b hover:bg-muted/30">
                                  <td className="px-4 py-2">{row.id}</td>
                                  <td className="px-4 py-2 font-mono text-xs">{row.sku}</td>
                                  <td className="px-4 py-2">{row.name}</td>
                                  <td className="px-4 py-2">
                                    {new Intl.NumberFormat("en-US", {
                                      style: "currency",
                                      currency: "USD",
                                    }).format(parseFloat(row.price))}
                                  </td>
                                  <td className="px-4 py-2">{row.stock}</td>
                                </tr>
                              ))}
                            </tbody>
                          </table>
                        </div>
                      )}
                    </div>
                  ))
                )}
              </div>
            ) : (
              // Normal Table View with Context Menu Grouping
              <ClientVirtualTable
                fetchMode="server"
                data={flatData}
                rowCount={totalRows}
                columns={productColumns}
                enablePagination
                enableGrouping // Context Menu에서 Group By 옵션 활성화
                height="400px"
                pagination={pagination}
                onPaginationChange={setPagination}
                sorting={sorting}
                onSortingChange={setSorting}
                // 그룹핑 상태 연결
                grouping={grouping}
                onGroupingChange={handleGroupingChange}
              />
            )}
          </div>
        </LoadingOverlay>
      </CardContent>
    </Card>
  );
}

// ============================================================
// Pattern 3: Custom Service (Server-Side with Joins)
// ============================================================

function CustomServiceTable() {
  const [data, setData] = React.useState<OrderWithDetails[]>([]);
  const [totalRows, setTotalRows] = React.useState(0);
  const [isLoading, setIsLoading] = React.useState(true);

  // Table state
  const [pagination, setPagination] = React.useState<PaginationState>({
    pageIndex: 0,
    pageSize: 10,
  });
  const [sorting, setSorting] = React.useState<SortingState>([]);
  const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([]);
  const [globalFilter, setGlobalFilter] = React.useState("");

  // Fetch data on state change
  React.useEffect(() => {
    const fetchData = async () => {
      setIsLoading(true);
      try {
        const result = await getOrderTableData({
          pagination,
          sorting,
          columnFilters,
          globalFilter,
        });
        setData(result.data);
        setTotalRows(result.totalRows);
      } catch (error) {
        console.error("Failed to fetch orders:", error);
      } finally {
        setIsLoading(false);
      }
    };

    fetchData();
  }, [pagination, sorting, columnFilters, globalFilter]);

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center gap-2">
          <CardTitle>Pattern 3: Custom Service</CardTitle>
          <Badge variant="outline">fetchMode=&quot;server&quot;</Badge>
          <Badge variant="secondary">DrizzleTableAdapter</Badge>
        </div>
        <CardDescription>
          <code>DrizzleTableAdapter</code>를 도구로 사용하여 복잡한 조인 쿼리를 직접 작성합니다.
          <br />
          <span className="text-muted-foreground">
            적합: 여러 테이블 조인, 복잡한 비즈니스 로직
          </span>
          <br />
          <span className="text-amber-600 text-sm">
            ⚠️ 그룹핑: 가상 컬럼(조인 결과)은 서버 GROUP BY 불가
          </span>
        </CardDescription>
      </CardHeader>
      <CardContent>
        <LoadingOverlay isLoading={isLoading}>
          <div className="h-[500px]">
            <ClientVirtualTable
              fetchMode="server"
              data={data}
              rowCount={totalRows}
              columns={orderColumns}
              isLoading={false}
              enablePagination
              enableGrouping={false}
              height="100%"
              pagination={pagination}
              onPaginationChange={setPagination}
              sorting={sorting}
              onSortingChange={setSorting}
              columnFilters={columnFilters}
              onColumnFiltersChange={setColumnFilters}
              globalFilter={globalFilter}
              onGlobalFilterChange={setGlobalFilter}
            />
          </div>
        </LoadingOverlay>
      </CardContent>
    </Card>
  );
}

// ============================================================
// Main Page
// ============================================================

export default function TableV2TestPage() {
  return (
    <div className="container py-6 space-y-6">
      <div>
        <h1 className="text-3xl font-bold tracking-tight">
          ClientVirtualTable V2 - 데이터 페칭 패턴 테스트
        </h1>
        <p className="text-muted-foreground mt-2">
          GUIDE.md에 정의된 데이터 페칭 패턴과 그룹핑 처리 방법을 테스트합니다.
          <br />
          테스트 전 시딩이 필요합니다: <code className="bg-muted px-1 rounded">npx tsx db/seeds/test-table-v2.ts</code>
        </p>
      </div>

      <Tabs defaultValue="pattern1" className="space-y-4">
        <TabsList className="grid w-full grid-cols-4">
          <TabsTrigger value="pattern1">
            1. Client-Side
          </TabsTrigger>
          <TabsTrigger value="pattern2">
            2. Factory Service
          </TabsTrigger>
          <TabsTrigger value="pattern2b">
            2-B. Server Grouping
          </TabsTrigger>
          <TabsTrigger value="pattern3">
            3. Custom Service
          </TabsTrigger>
        </TabsList>

        <TabsContent value="pattern1">
          <ClientSideTable />
        </TabsContent>

        <TabsContent value="pattern2">
          <FactoryServiceTable />
        </TabsContent>

        <TabsContent value="pattern2b">
          <ServerGroupingTable />
        </TabsContent>

        <TabsContent value="pattern3">
          <CustomServiceTable />
        </TabsContent>
      </Tabs>

      {/* Summary Table */}
      <Card>
        <CardHeader>
          <CardTitle>패턴별 그룹핑 지원 현황</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b">
                  <th className="text-left py-2 px-4">패턴</th>
                  <th className="text-left py-2 px-4">그룹핑 방식</th>
                  <th className="text-left py-2 px-4">가상 컬럼 지원</th>
                  <th className="text-left py-2 px-4">비고</th>
                </tr>
              </thead>
              <tbody>
                <tr className="border-b">
                  <td className="py-2 px-4 font-medium">1. Client-Side</td>
                  <td className="py-2 px-4">
                    <Badge className="bg-emerald-500">TanStack Grouping</Badge>
                  </td>
                  <td className="py-2 px-4">
                    <Badge className="bg-emerald-500">✓ 지원</Badge>
                  </td>
                  <td className="py-2 px-4 text-muted-foreground">
                    메모리에서 처리, 전체 데이터 필요
                  </td>
                </tr>
                <tr className="border-b">
                  <td className="py-2 px-4 font-medium">2. Factory Service</td>
                  <td className="py-2 px-4">
                    <Badge variant="outline">미지원</Badge>
                  </td>
                  <td className="py-2 px-4">-</td>
                  <td className="py-2 px-4 text-muted-foreground">
                    별도 구현 필요 (2-B 참고)
                  </td>
                </tr>
                <tr className="border-b">
                  <td className="py-2 px-4 font-medium">2-B. Server Grouping</td>
                  <td className="py-2 px-4">
                    <Badge className="bg-blue-500">DB GROUP BY</Badge>
                  </td>
                  <td className="py-2 px-4">
                    <Badge variant="destructive">✗ 불가</Badge>
                  </td>
                  <td className="py-2 px-4 text-muted-foreground">
                    serverGroupable 컬럼만 가능
                  </td>
                </tr>
                <tr>
                  <td className="py-2 px-4 font-medium">3. Custom Service</td>
                  <td className="py-2 px-4">
                    <Badge variant="secondary">커스텀 구현</Badge>
                  </td>
                  <td className="py-2 px-4">
                    <Badge variant="secondary">선택적</Badge>
                  </td>
                  <td className="py-2 px-4 text-muted-foreground">
                    쿼리 설계에 따라 다름
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </CardContent>
      </Card>

      {/* Column Groupability Info */}
      <Card>
        <CardHeader>
          <CardTitle>컬럼별 서버 그룹핑 지원 여부</CardTitle>
          <CardDescription>
            <code>meta.serverGroupable</code> 플래그로 DB GROUP BY 가능 여부를 표시합니다.
            <br />
            헤더 우클릭 시 &quot;Group by [Column]&quot; 메뉴가 표시됩니다.
          </CardDescription>
        </CardHeader>
        <CardContent>
          <div className="flex flex-wrap gap-2">
            {productColumns.map((col) => {
              if (!('accessorKey' in col)) return null;
              const meta = col.meta as { serverGroupable?: boolean } | undefined;
              const isGroupable = meta?.serverGroupable;
              return (
                <Badge
                  key={col.accessorKey as string}
                  variant={isGroupable ? "default" : "outline"}
                  className={isGroupable ? "bg-emerald-500" : ""}
                >
                  {col.accessorKey as string}
                  {isGroupable && " ✓"}
                </Badge>
              );
            })}
          </div>
        </CardContent>
      </Card>
    </div>
  );
}
